/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package clockanimation;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.JPanel;

/**
 *
 * @author trn
 */
public class Canvas extends JPanel
{
  private Display display;
  private Graphics g;
  private String time;
  private String prevTime;
  private String date;
  private String prevDate;
  private static final int TIME_HEIGHT_ALTERATION = 100;
  private static final int CLOCK_HEIGHT_ALTERATION = 30;
  private static final int CLOCK_SIZE = 180;
  private static final int SCALE_SIZE = CLOCK_SIZE - 15;
  private static final int POINTER_LENGTH = 80;
  private static final Font DATE_FONT = Font.decode("Arial-PLAIN-25");
  private static final Font TIME_FONT = Font.decode("Arial-BOLD-28");
  private static final Font NUMBERS_FONT = Font.decode("Arial-PLAIN-12");

  public Canvas(Display display)
  {
    this.display = display;
    prevTime = new SimpleDateFormat(
        "HH;mm;ss").format(new Date());
    prevDate = new SimpleDateFormat(
        "dd;MM;yyyy").format(new Date());
  }

  @Override
  public void paintComponent(Graphics g)
  {
    this.g = g;

    drawTime();
    drawDate();
    drawClock();
  }

  private void drawTime()
  {
    g.setFont(TIME_FONT);
    g.setColor(display.getBackground());
    g.drawString(prevTime, (int)(getSize().width / 2. - getStringWidth(g,
        prevTime) / 2.), (int)(getSize().height / 2. - 25
        + TIME_HEIGHT_ALTERATION));
    g.setColor(Color.BLACK);
    g.drawString(time,
        (int)(getSize().width / 2. - getStringWidth(g, time) / 2.), (int)(getSize().height
        / 2. - 25 + TIME_HEIGHT_ALTERATION));
    prevTime = time;
  }

  private void drawDate()
  {
    g.setFont(DATE_FONT);
    g.setColor(display.getBackground());
    g.drawString(prevDate, (int)(getSize().width / 2. - getStringWidth(g,
        prevDate) / 2.), (int)(getSize().height
        / 2. + TIME_HEIGHT_ALTERATION));
    g.setColor(Color.BLACK);
    g.drawString(date,
        (int)(getSize().width / 2. - getStringWidth(g, date) / 2.), (int)(getSize().height
        / 2. + TIME_HEIGHT_ALTERATION));
    prevDate = date;
  }

  private void drawClock()
  {
    //Rahmen
    g.drawOval((int)((getSize().width - CLOCK_SIZE) / 2.), (int)((getSize().height
        / 2. - CLOCK_SIZE)) + CLOCK_HEIGHT_ALTERATION, CLOCK_SIZE, CLOCK_SIZE);
    g.drawOval(getClockCenter()[0] - (CLOCK_SIZE + 10) / 2, getClockCenter()[1] - (CLOCK_SIZE
        + 10) / 2, CLOCK_SIZE + 10, CLOCK_SIZE + 10);

    // Alten Sekundenzeiger noch vorm Zeichnen der Skala löschen
    drawPointer(display.getTime().getSeconds() - 1, POINTER_LENGTH, 60, display.
        getBackground());

    // Skala
    for(int i = 0; i < 60; i++)
      drawPointer(i, 90, 60, Color.LIGHT_GRAY);
    g.setColor(display.getBackground());
    g.fillOval(getClockCenter()[0] - SCALE_SIZE / 2, getClockCenter()[1] - SCALE_SIZE
        / 2, SCALE_SIZE, SCALE_SIZE);
    g.setColor(Color.BLACK);

    for(int i = 0; i<60; i+=5)
      drawPointer(i, 90, 60, Color.BLACK);
    g.setColor(display.getBackground());
    g.fillOval(getClockCenter()[0] - (SCALE_SIZE - 15) / 2, getClockCenter()[1] - (SCALE_SIZE
        - 15)
        / 2, SCALE_SIZE - 15, SCALE_SIZE - 15);
    g.setColor(Color.BLACK);

    // Minutenzeiger
    drawPointer(display.getTime().getMinutes(), POINTER_LENGTH, 60, Color.BLACK);

    //Stundenzeiger
    drawPointer(display.getTime().getHours() * 60 * 60 + display.getTime().
        getMinutes() * 60 + display.getTime().getSeconds(), POINTER_LENGTH - 30, 12
        * 60 * 60, Color.BLACK);

    // Sekundenzeiger
    drawPointer(display.getTime().getSeconds(), POINTER_LENGTH - 5, 60,
        Color.RED);

    // Zahlen
    for(int i = 1; i <= 12; i++)
    {
      {
      double cos = Math.cos(getAngle(i, 12));
      double sin = Math.sin(getAngle(i, 12));
      String roman = getRoman(i);
      g.setFont(NUMBERS_FONT);
      g.setColor(Color.BLACK);
      drawCenteredString(i+"", (int)(-cos
          * 65) + getClockCenter()[0]+2,
          (int)(-sin * 65) + getClockCenter()[1]+5);
      }
    }
  }

  private String getRoman(int i)
  {
    if(i == 1)
      return "I";
    if(i == 2)
      return "II";
    if(i == 3)
      return "III";
    if(i == 4)
      return "IV";
    if(i == 5)
      return "V";
    if(i == 6)
      return "VI";
    if(i == 7)
      return "VII";
    if(i == 8)
      return "VIII";
    if(i == 9)
      return "IX";
    if(i == 10)
      return "X";
    if(i == 11)
      return "XI";
    else
      return "XII";
  }

  private void drawCenteredString(String s, int x, int y)
  {
    x -= getStringWidth(g, s)/2.;
    g.drawString(s, x, y);
  }

  private void drawPointer(int position, int length, int scaling, Color c)
  {
    double angle = getAngle(position, scaling);
    double cos = Math.cos(angle);
    double sin = Math.sin(angle);
    Color prev = g.getColor();
    g.setColor(c);
    g.drawLine(getClockCenter()[0], getClockCenter()[1], (int)(-cos
        * length) + getClockCenter()[0],
        (int)(-sin * length) + getClockCenter()[1]);
    g.setColor(prev);
  }

  private double getAngle(int position, int scaling)
  {
    return position * 2 * Math.PI / scaling + Math.PI / 2;
  }

  private int[] getClockCenter()
  {
    int x = (int)(getSize().width / 2.);
    int y = (int)(getSize().height / 2. - CLOCK_SIZE / 2.
        + CLOCK_HEIGHT_ALTERATION);
    return new int[]
        {
          x, y
        };
  }

  public void showTime()
  {
    this.date = display.getTime().getDateString();
    this.time = display.getTime().getTimeString();
    repaint();
  }

  private int getStringWidth(Graphics g, String s)
  {
    int spaces = 0;
    for(int i = 0; i < s.length(); i++)
      if(s.charAt(i) == ' ')
        spaces++;
    return (int)g.getFontMetrics().getStringBounds(s, g).getWidth() + spaces * 2;
  }

  private int getStringHeight(Graphics g, String s)
  {
    return (int)g.getFontMetrics().getStringBounds(s, g).getHeight();
  }

}
